﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace Test
{

    delegate void OnRecievHandler(byte[] buf,int len);

    [StructLayout(LayoutKind.Sequential)]
    public struct ipHdr
    {
        public byte h_len;//4位首部长度
        public byte version;//4位IP版本号
        public byte tos; //8位服务类型TOS
        public short total_len; //16位总长度（字节）
        public short idflag; //16位标识
        public short frag_and_flags; //3位标志位
        public byte ttl; //8位生存时间 TTL
        public byte proto; //8位协议 (TCP, UDP 或其他)
        public short checksum; //16位IP首部校验和
        public uint sourceIP; //32位源IP地址
        public uint destIP; //32位目的IP地址
    };

    [StructLayout(LayoutKind.Sequential)]
    public struct tcpHdr
    {
        public short src_port;    //源端口号   
        public short dst_port;    //目的端口号   
        public uint seq_no;        //序列号   
        public uint ack_no;        //确认号  
        public byte reserved_1; //保留6位中的4位首部长度   
        public byte h_len;        //tcp头部长度   
        public byte flag;       //6位标志   
        public byte reseverd_2; //保留6位中的2位
        public short wnd_size;    //16位窗口大小   
        public short chk_sum;     //16位TCP检验和   
        public short urgt_p;      //16为紧急指针
    };

    [StructLayout(LayoutKind.Sequential)]
    public struct udpHdr
    {
        public short src_port; //远端口号   
        public short dst_port; //目的端口号   
        public short h_len;      //udp头部长度   
        public short chk_sum;  //16位udp检验和  
    };

    [StructLayout(LayoutKind.Sequential)]
    public struct icmpHdr
    {
        public byte icmp_type;   //类型   
        public byte code;        //代码   
        public short chk_sum;    //16位检验和 
    } ;

    [StructLayout(LayoutKind.Explicit)]
    public struct ethHdr
    {

        [FieldOffset(0)]
        public byte[] dstmac; //目标mac地址   
        [FieldOffset(6)]
        public byte[] srcmac; //源mac地址   
        [FieldOffset(12)]
        public short eth_type; //以太网类型
    };

    public enum ProtocolType
    {
        Tcp = 0x01,
        Udp = 0x02,
        Icmp = 0x04,
        Unknown = 0x08
    };

    [StructLayout(LayoutKind.Sequential)]
    public struct pktInfo
    {
        public ProtocolType Ptype;
        public ipHdr IpHeader;
        public tcpHdr TcpHeader;
        public udpHdr UdpHeader;
        public icmpHdr IcmpHeader;
        public byte[] buffer;
        public int blen;
    };

    class Program
    {
        [DllImport("NetDataSniff.dll", EntryPoint = "SktAddrList", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        public static extern void SktAddrList(ref char[] addrs);

        [DllImport("NetDataSniff.dll", EntryPoint = "SktDataStart", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool SktDataStart([In] string ip, int len,OnRecievHandler callback);

        [DllImport("NetDataSniff.dll", EntryPoint = "SktPktInfo", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        public static extern pktInfo SktPktInfo(byte[] buf, int len);

        [DllImport("NetDataSniff.dll", EntryPoint = "SktStop", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        private static extern void SktStop();

        [DllImport("NetDataSniff.dll", EntryPoint = "add", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        private static extern int add(int a, int b);

        static void Main(string[] args)
        {
            string pwd = "pass你";
            byte[] b = Encoding.Default.GetBytes(pwd);
            byte[] d = Encoding.UTF8.GetBytes(pwd);
            //char[] addrs=null;
            //SktAddrList(ref addrs);
            //string ips = "192.168.1.250";

            //if (!SktDataStart(ips, ips.Length, OnRecieveCallback))
            //{
            //    Console.WriteLine("error");
            //}
            //else
            //{
            //    Console.WriteLine("等待接收...");
            //    Console.ReadKey();
            //}
            //SktStop();
        }

        static void OnRecieveCallback(byte[] buf, int len)
        {
            pktInfo pkt = SktPktInfo(buf, len);
          
           Console.WriteLine(pkt.Ptype.ToString());
        }
    }
}
